# coding: utf-8

# 作者：雪山凌狐
# 日期：2023-01-22

from wxpy import Bot, embed, ResponseError, Friend
from openpyxl import load_workbook
import sys
from time import sleep
import random
from alive_progress import alive_bar

template = """{}，新年快乐！[庆祝][庆祝][庆祝][烟花][烟花][烟花]\r{}恭祝您兔年大吉！身体健康！万事如意！大展宏兔！"""
switch_send = True
switch_update_send_status = True
switch_update_send_content = True
switch_sleep = True

def jitter(n=5):
    return random.randint(0, n)


if __name__ == '__main__':
    if len(sys.argv) <= 1:
        print("请输入执行参数")
    else:
        bot = Bot(cache_path=True)
        bot.enable_puid(path="wxpy_puid.pkl")

        @bot.register(Friend, run_async=True)
        def print_all_msg(msg):
            print(msg)

        wb = load_workbook("wxrobot.xlsx")
        ws = wb.active
        if sys.argv[1] == "init": 
            my_friends = bot.friends()
            for i in range(len(my_friends)):
                ws.cell(row=i+2, column=1).value = my_friends[i].name
                ws.cell(row=i+2, column=2).value = my_friends[i].puid
        elif sys.argv[1] == "batch_send":
            # 获取出要发送的人清单
            send_list = []
            for i in range(2, ws.max_row + 1):
                need_send = ws.cell(row=i, column=5).value
                has_send = ws.cell(row=i, column=6).value
                if need_send == 1 and has_send == 0:
                    name = ws.cell(row=i, column=1).value
                    puid = ws.cell(row=i, column=2).value
                    call_name = ws.cell(row=i, column=3).value
                    my_name = ws.cell(row=i, column=4).value
                    need_send_content = template.format(call_name, my_name)
                    row_num = i
                    send_list.append((name, puid, need_send_content, row_num))
            print("待发送总数：", len(send_list))
            # print("所有待发送人和信息：", send_list)

            # 通过 puid 寻找对应要发送的人并发送，注意个别人的 puid 可能会重复！！在编辑完内容检查的时候要特别注意检查重复值！！
            with alive_bar(len(send_list)) as bar:
                for i in range(len(send_list)):
                    puid = send_list[i][1]
                    need_send_content = send_list[i][2]
                    try:
                        # print("此次待发送信息：", puid, need_send_content)
                        friend = bot.friends().search(puid=puid)[0]
                        # print("此次待发送人：", friend)
                        if switch_send:
                            # 发送
                            friend.send(need_send_content)
                            print("给{}的消息发送成功！".format(friend.name))
                        if switch_update_send_status:
                            # 更新已发送状态
                            ws.cell(row=send_list[i][3], column=6).value = 1
                        if switch_update_send_content:
                            # 更新已发送内容
                            ws.cell(row=send_list[i][3], column=7).value = need_send_content              
                    except ResponseError as e:
                        ws.cell(row=send_list[i][3], column=8).value = "%s,%s" % (e.err_code, e.err_msg)  
                        wb.save("wxrobot.xlsx")              
                        print(e.err_code, e.err_msg) 
                        # 之前实测不会展示失败信息，只会在监控返回值中（控制台）看到信息，比如被删除好友等，但不会产生失败信息并写入，理论上这一行可能没用    
                        print("发送失败，信息：（%s, %s, %s, %s）" % (puid, send_list[i][0], friend, need_send_content))
                    except Exception as e:
                        ws.cell(row=send_list[i][3], column=8).value = "%s,%s" % ("其他错误", e)
                        wb.save("wxrobot.xlsx")                 
                        print(e)                        

                    if switch_sleep:
                        if i < len(send_list) - 1:
                            # print("等待 10 秒左右继续发...")
                            sleep(10 + jitter())

                        if i % 30 == 0:
                            # 发 30 个休息一下，避免被检测
                            sleep(30 + jitter())

                    bar()

        wb.save("wxrobot.xlsx")
        wb.close()

        embed()
        # bot.logout()
